<?php
/**
 * Twenty Twelve functions and definitions.
 *
 * Sets up the theme and provides some helper functions, which are used
 * in the theme as custom template tags. Others are attached to action and
 * filter hooks in WordPress to change core functionality.
 *
 * When using a child theme (see http://codex.wordpress.org/Theme_Development and
 * http://codex.wordpress.org/Child_Themes), you can override certain functions
 * (those wrapped in a function_exists() call) by defining them first in your child theme's
 * functions.php file. The child theme's functions.php file is included before the parent
 * theme's file, so the child theme functions would be used.
 *
 * Functions that are not pluggable (not wrapped in function_exists()) are instead attached
 * to a filter or action hook.
 *
 * For more information on hooks, actions, and filters, see http://codex.wordpress.org/Plugin_API.
 *
 * @package WordPress
 * @subpackage Twenty_Twelve
 * @since Twenty Twelve 1.0
 */

/**
 * Sets up the content width value based on the theme's design and stylesheet.
 */
if ( ! isset( $content_width ) )
	$content_width = 625;

/**
 * Sets up theme defaults and registers the various WordPress features that
 * Twenty Twelve supports.
 *
 * @uses load_theme_textdomain() For translation/localization support.
 * @uses add_editor_style() To add a Visual Editor stylesheet.
 * @uses add_theme_support() To add support for post thumbnails, automatic feed links,
 * 	custom background, and post formats.
 * @uses register_nav_menu() To add support for navigation menus.
 * @uses set_post_thumbnail_size() To set a custom post thumbnail size.
 *
 * @since Twenty Twelve 1.0
 */
function twentytwelve_setup() {
	/*
	 * Makes Twenty Twelve available for translation.
	 *
	 * Translations can be added to the /languages/ directory.
	 * If you're building a theme based on Twenty Twelve, use a find and replace
	 * to change 'twentytwelve' to the name of your theme in all the template files.
	 */
	load_theme_textdomain( 'twentytwelve', get_template_directory() . '/languages' );

	// This theme styles the visual editor with editor-style.css to match the theme style.
	add_editor_style();

	// Adds RSS feed links to <head> for posts and comments.
	add_theme_support( 'automatic-feed-links' );

	// This theme supports a variety of post formats.
	add_theme_support( 'post-formats', array( 'aside', 'image', 'link', 'quote', 'status' ) );

	// This theme uses wp_nav_menu() in one location.
	register_nav_menu( 'primary', __( 'Primary Menu', 'twentytwelve' ) );

	/*
	 * This theme supports custom background color and image, and here
	 * we also set up the default background color.
	 */
	add_theme_support( 'custom-background', array(
		'default-color' => 'e6e6e6',
	) );

	// This theme uses a custom image size for featured images, displayed on "standard" posts.
	add_theme_support( 'post-thumbnails' );
	set_post_thumbnail_size( 624, 9999 ); // Unlimited height, soft crop
}
add_action( 'after_setup_theme', 'twentytwelve_setup' );

/**
 * Adds support for a custom header image.
 */
require( get_template_directory() . '/inc/custom-header.php' );

/**
 * Enqueues scripts and styles for front-end.
 *
 * @since Twenty Twelve 1.0
 */
function twentytwelve_scripts_styles() {
	global $wp_styles;

	/*
	 * Adds JavaScript to pages with the comment form to support
	 * sites with threaded comments (when in use).
	 */
	if ( is_singular() && comments_open() && get_option( 'thread_comments' ) )
		wp_enqueue_script( 'comment-reply' );

	/*
	 * Adds JavaScript for handling the navigation menu hide-and-show behavior.
	 */
	wp_enqueue_script( 'twentytwelve-navigation', get_template_directory_uri() . '/js/navigation.js', array(), '1.0', true );

	/*
	 * Loads our special font CSS file.
	 *
	 * The use of Open Sans by default is localized. For languages that use
	 * characters not supported by the font, the font can be disabled.
	 *
	 * To disable in a child theme, use wp_dequeue_style()
	 * function mytheme_dequeue_fonts() {
	 *     wp_dequeue_style( 'twentytwelve-fonts' );
	 * }
	 * add_action( 'wp_enqueue_scripts', 'mytheme_dequeue_fonts', 11 );
	 */

	/* translators: If there are characters in your language that are not supported
	   by Open Sans, translate this to 'off'. Do not translate into your own language. */
	if ( 'off' !== _x( 'on', 'Open Sans font: on or off', 'twentytwelve' ) ) {
		$subsets = 'latin,latin-ext';

		/* translators: To add an additional Open Sans character subset specific to your language, translate
		   this to 'greek', 'cyrillic' or 'vietnamese'. Do not translate into your own language. */
		$subset = _x( 'no-subset', 'Open Sans font: add new subset (greek, cyrillic, vietnamese)', 'twentytwelve' );

		if ( 'cyrillic' == $subset )
			$subsets .= ',cyrillic,cyrillic-ext';
		elseif ( 'greek' == $subset )
			$subsets .= ',greek,greek-ext';
		elseif ( 'vietnamese' == $subset )
			$subsets .= ',vietnamese';

		$protocol = is_ssl() ? 'https' : 'http';
		$query_args = array(
			'family' => 'Open+Sans:400italic,700italic,400,700',
			'subset' => $subsets,
		);
		wp_enqueue_style( 'twentytwelve-fonts', add_query_arg( $query_args, "$protocol://fonts.googleapis.com/css" ), array(), null );
	}

	/*
	 * Loads our main stylesheet.
	 */
	wp_enqueue_style( 'twentytwelve-style', get_stylesheet_uri() );

	/*
	 * Loads the Internet Explorer specific stylesheet.
	 */
	wp_enqueue_style( 'twentytwelve-ie', get_template_directory_uri() . '/css/ie.css', array( 'twentytwelve-style' ), '20121010' );
	$wp_styles->add_data( 'twentytwelve-ie', 'conditional', 'lt IE 9' );
}
add_action( 'wp_enqueue_scripts', 'twentytwelve_scripts_styles' );

/**
 * Creates a nicely formatted and more specific title element text
 * for output in head of document, based on current view.
 *
 * @since Twenty Twelve 1.0
 *
 * @param string $title Default title text for current view.
 * @param string $sep Optional separator.
 * @return string Filtered title.
 */
function twentytwelve_wp_title( $title, $sep ) {
	global $paged, $page;

	if ( is_feed() )
		return $title;

	// Add the site name.
	$title .= get_bloginfo( 'name' );

	// Add the site description for the home/front page.
	$site_description = get_bloginfo( 'description', 'display' );
	if ( $site_description && ( is_home() || is_front_page() ) )
		$title = "$title $sep $site_description";

	// Add a page number if necessary.
	if ( $paged >= 2 || $page >= 2 )
		$title = "$title $sep " . sprintf( __( 'Page %s', 'twentytwelve' ), max( $paged, $page ) );

	return $title;
}
add_filter( 'wp_title', 'twentytwelve_wp_title', 10, 2 );

/**
 * Makes our wp_nav_menu() fallback -- wp_page_menu() -- show a home link.
 *
 * @since Twenty Twelve 1.0
 */
function twentytwelve_page_menu_args( $args ) {
	if ( ! isset( $args['show_home'] ) )
		$args['show_home'] = true;
	return $args;
}
add_filter( 'wp_page_menu_args', 'twentytwelve_page_menu_args' );

/**
 * Registers our main widget area and the front page widget areas.
 *
 * @since Twenty Twelve 1.0
 */
function twentytwelve_widgets_init() {
	register_sidebar( array(
		'name' => __( 'Main Sidebar', 'twentytwelve' ),
		'id' => 'sidebar-1',
		'description' => __( 'Appears on posts and pages except the optional Front Page template, which has its own widgets', 'twentytwelve' ),
		'before_widget' => '<aside id="%1$s" class="widget %2$s">',
		'after_widget' => '</aside>',
		'before_title' => '<h3 class="widget-title">',
		'after_title' => '</h3>',
	) );

	register_sidebar( array(
		'name' => __( 'First Front Page Widget Area', 'twentytwelve' ),
		'id' => 'sidebar-2',
		'description' => __( 'Appears when using the optional Front Page template with a page set as Static Front Page', 'twentytwelve' ),
		'before_widget' => '<aside id="%1$s" class="widget %2$s">',
		'after_widget' => '</aside>',
		'before_title' => '<h3 class="widget-title">',
		'after_title' => '</h3>',
	) );

	register_sidebar( array(
		'name' => __( 'Second Front Page Widget Area', 'twentytwelve' ),
		'id' => 'sidebar-3',
		'description' => __( 'Appears when using the optional Front Page template with a page set as Static Front Page', 'twentytwelve' ),
		'before_widget' => '<aside id="%1$s" class="widget %2$s">',
		'after_widget' => '</aside>',
		'before_title' => '<h3 class="widget-title">',
		'after_title' => '</h3>',
	) );
	
	register_sidebar( array(
		'name' => __( 'Header Shopping Cart Widget Area', 'twentytwelve' ),
		'id' => 'sidebar-4',
		'description' => __( 'For placing the dropdown shopping cart into the header of the website.', 'twentytwelve' ),
		'before_widget' => '<aside id="%1$s" class="widget %2$s">',
		'after_widget' => '</aside>',
		'before_title' => '<h3 class="widget-title">',
		'after_title' => '</h3>',
	) );
	
	register_sidebar( array(
		'name' => __( 'Header Search Widget Area', 'twentytwelve' ),
		'id' => 'sidebar-5',
		'description' => __( 'Include the wordpress search bar in the header navigation area.', 'twentytwelve' ),
		'before_widget' => '<aside id="%1$s" class="widget %2$s">',
		'after_widget' => '</aside>',
		'before_title' => '<h3 class="widget-title">',
		'after_title' => '</h3>',
	) );
	
	register_sidebar( array(
		'name' => __( 'Sidebar Store Categories', 'twentytwelve' ),
		'id' => 'sidebar-6',
		'description' => __( 'Sidebar Space For WooCommerce Category Widget', 'twentytwelve' ),
		'before_widget' => '<aside id="%1$s" class="widget %2$s">',
		'after_widget' => '</aside>',
		'before_title' => '<h3 class="widget-title">',
		'after_title' => '</h3>',
	) );
	
	register_sidebar( array(
		'name' => __( 'Header Dropdown Menu', 'twentytwelve' ),
		'id' => 'sidebar-7',
		'description' => __( 'Sidebar Space For WooCommerce Category Widget', 'twentytwelve' ),
		'before_widget' => '<aside id="%1$s" class="widget %2$s">',
		'after_widget' => '</aside>',
		'before_title' => '<h3 class="widget-title">',
		'after_title' => '</h3>',
	) );
	
	register_sidebar( array(
		'name' => __( 'Pagesearch', 'twentytwelve' ),
		'id' => 'sidebar-8',
		'description' => __( 'Search Form For Inside The WooCommerce Search Page', 'twentytwelve' ),
		'before_widget' => '<aside id="%1$s" class="widget %2$s">',
		'after_widget' => '</aside>',
		'before_title' => '<h3 class="widget-title">',
		'after_title' => '</h3>',
	) );
	
	register_sidebar( array(
		'name' => __( 'Featuredproducts', 'twentytwelve' ),
		'id' => 'sidebar-9',
		'description' => __( 'Featured Products Widget', 'twentytwelve' ),
		'before_widget' => '<aside id="%1$s" class="widget %2$s">',
		'after_widget' => '</aside>',
		'before_title' => '<h3 class="widget-title">',
		'after_title' => '</h3>',
	) );
}
add_action( 'widgets_init', 'twentytwelve_widgets_init' );

if ( ! function_exists( 'twentytwelve_content_nav' ) ) :
/**
 * Displays navigation to next/previous pages when applicable.
 *
 * @since Twenty Twelve 1.0
 */
function twentytwelve_content_nav( $html_id ) {
	global $wp_query;

	$html_id = esc_attr( $html_id );

	if ( $wp_query->max_num_pages > 1 ) : ?>
		<nav id="<?php echo $html_id; ?>" class="navigation" role="navigation">
			<h3 class="assistive-text"><?php _e( 'Post navigation', 'twentytwelve' ); ?></h3>
			<div class="nav-previous alignleft"><?php next_posts_link( __( '<span class="meta-nav">&larr;</span> Older posts', 'twentytwelve' ) ); ?></div>
			<div class="nav-next alignright"><?php previous_posts_link( __( 'Newer posts <span class="meta-nav">&rarr;</span>', 'twentytwelve' ) ); ?></div>
		</nav><!-- #<?php echo $html_id; ?> .navigation -->
	<?php endif;
}
endif;

if ( ! function_exists( 'twentytwelve_comment' ) ) :
/**
 * Template for comments and pingbacks.
 *
 * To override this walker in a child theme without modifying the comments template
 * simply create your own twentytwelve_comment(), and that function will be used instead.
 *
 * Used as a callback by wp_list_comments() for displaying the comments.
 *
 * @since Twenty Twelve 1.0
 */
function twentytwelve_comment( $comment, $args, $depth ) {
	$GLOBALS['comment'] = $comment;
	switch ( $comment->comment_type ) :
		case 'pingback' :
		case 'trackback' :
		// Display trackbacks differently than normal comments.
	?>
	<li <?php comment_class(); ?> id="comment-<?php comment_ID(); ?>">
		<p><?php _e( 'Pingback:', 'twentytwelve' ); ?> <?php comment_author_link(); ?> <?php edit_comment_link( __( '(Edit)', 'twentytwelve' ), '<span class="edit-link">', '</span>' ); ?></p>
	<?php
			break;
		default :
		// Proceed with normal comments.
		global $post;
	?>
	<li <?php comment_class(); ?> id="li-comment-<?php comment_ID(); ?>">
		<article id="comment-<?php comment_ID(); ?>" class="comment">
			<header class="comment-meta comment-author vcard">
				<?php
					echo get_avatar( $comment, 44 );
					printf( '<cite class="fn">%1$s %2$s</cite>',
						get_comment_author_link(),
						// If current post author is also comment author, make it known visually.
						( $comment->user_id === $post->post_author ) ? '<span> ' . __( 'Post author', 'twentytwelve' ) . '</span>' : ''
					);
					printf( '<a href="%1$s"><time datetime="%2$s">%3$s</time></a>',
						esc_url( get_comment_link( $comment->comment_ID ) ),
						get_comment_time( 'c' ),
						/* translators: 1: date, 2: time */
						sprintf( __( '%1$s at %2$s', 'twentytwelve' ), get_comment_date(), get_comment_time() )
					);
				?>
			</header><!-- .comment-meta -->

			<?php if ( '0' == $comment->comment_approved ) : ?>
				<p class="comment-awaiting-moderation"><?php _e( 'Your comment is awaiting moderation.', 'twentytwelve' ); ?></p>
			<?php endif; ?>

			<section class="comment-content comment">
				<?php comment_text(); ?>
				<?php edit_comment_link( __( 'Edit', 'twentytwelve' ), '<p class="edit-link">', '</p>' ); ?>
			</section><!-- .comment-content -->

			<div class="reply">
				<?php comment_reply_link( array_merge( $args, array( 'reply_text' => __( 'Reply', 'twentytwelve' ), 'after' => ' <span>&darr;</span>', 'depth' => $depth, 'max_depth' => $args['max_depth'] ) ) ); ?>
			</div><!-- .reply -->
		</article><!-- #comment-## -->
	<?php
		break;
	endswitch; // end comment_type check
}
endif;

if ( ! function_exists( 'twentytwelve_entry_meta' ) ) :
/**
 * Prints HTML with meta information for current post: categories, tags, permalink, author, and date.
 *
 * Create your own twentytwelve_entry_meta() to override in a child theme.
 *
 * @since Twenty Twelve 1.0
 */
function twentytwelve_entry_meta() {
	// Translators: used between list items, there is a space after the comma.
	$categories_list = get_the_category_list( __( ', ', 'twentytwelve' ) );

	// Translators: used between list items, there is a space after the comma.
	$tag_list = get_the_tag_list( '', __( ', ', 'twentytwelve' ) );

	$date = sprintf( '<a href="%1$s" title="%2$s" rel="bookmark"><time class="entry-date" datetime="%3$s">%4$s</time></a>',
		esc_url( get_permalink() ),
		esc_attr( get_the_time() ),
		esc_attr( get_the_date( 'c' ) ),
		esc_html( get_the_date() )
	);

	$author = sprintf( '<span class="author vcard"><a class="url fn n" href="%1$s" title="%2$s" rel="author">%3$s</a></span>',
		esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ),
		esc_attr( sprintf( __( 'View all posts by %s', 'twentytwelve' ), get_the_author() ) ),
		get_the_author()
	);

	// Translators: 1 is category, 2 is tag, 3 is the date and 4 is the author's name.
	if ( $tag_list ) {
		$utility_text = __( 'This entry was posted in %1$s and tagged %2$s on %3$s<span class="by-author"> by %4$s</span>.', 'twentytwelve' );
	} elseif ( $categories_list ) {
		$utility_text = __( 'This entry was posted in %1$s on %3$s<span class="by-author"> by %4$s</span>.', 'twentytwelve' );
	} else {
		$utility_text = __( 'This entry was posted on %3$s<span class="by-author"> by %4$s</span>.', 'twentytwelve' );
	}

	printf(
		$utility_text,
		$categories_list,
		$tag_list,
		$date,
		$author
	);
}
endif;

/**
 * Extends the default WordPress body class to denote:
 * 1. Using a full-width layout, when no active widgets in the sidebar
 *    or full-width template.
 * 2. Front Page template: thumbnail in use and number of sidebars for
 *    widget areas.
 * 3. White or empty background color to change the layout and spacing.
 * 4. Custom fonts enabled.
 * 5. Single or multiple authors.
 *
 * @since Twenty Twelve 1.0
 *
 * @param array Existing class values.
 * @return array Filtered class values.
 */
function twentytwelve_body_class( $classes ) {
	$background_color = get_background_color();

	if ( ! is_active_sidebar( 'sidebar-1' ) || is_page_template( 'page-templates/full-width.php' ) )
		$classes[] = 'full-width';

	if ( is_page_template( 'page-templates/front-page.php' ) ) {
		$classes[] = 'template-front-page';
		if ( has_post_thumbnail() )
			$classes[] = 'has-post-thumbnail';
		if ( is_active_sidebar( 'sidebar-2' ) && is_active_sidebar( 'sidebar-3' ) )
			$classes[] = 'two-sidebars';
	}

	if ( empty( $background_color ) )
		$classes[] = 'custom-background-empty';
	elseif ( in_array( $background_color, array( 'fff', 'ffffff' ) ) )
		$classes[] = 'custom-background-white';

	// Enable custom font class only if the font CSS is queued to load.
	if ( wp_style_is( 'twentytwelve-fonts', 'queue' ) )
		$classes[] = 'custom-font-enabled';

	if ( ! is_multi_author() )
		$classes[] = 'single-author';

	return $classes;
}
add_filter( 'body_class', 'twentytwelve_body_class' );

/**
 * Adjusts content_width value for full-width and single image attachment
 * templates, and when there are no active widgets in the sidebar.
 *
 * @since Twenty Twelve 1.0
 */
function twentytwelve_content_width() {
	if ( is_page_template( 'page-templates/full-width.php' ) || is_attachment() || ! is_active_sidebar( 'sidebar-1' ) ) {
		global $content_width;
		$content_width = 960;
	}
}
add_action( 'template_redirect', 'twentytwelve_content_width' );

/**
 * Add postMessage support for site title and description for the Theme Customizer.
 *
 * @since Twenty Twelve 1.0
 *
 * @param WP_Customize_Manager $wp_customize Theme Customizer object.
 * @return void
 */
function twentytwelve_customize_register( $wp_customize ) {
	$wp_customize->get_setting( 'blogname' )->transport = 'postMessage';
	$wp_customize->get_setting( 'blogdescription' )->transport = 'postMessage';
}
add_action( 'customize_register', 'twentytwelve_customize_register' );

/**
 * Binds JS handlers to make Theme Customizer preview reload changes asynchronously.
 *
 * @since Twenty Twelve 1.0
 */
function twentytwelve_customize_preview_js() {
	wp_enqueue_script( 'twentytwelve-customizer', get_template_directory_uri() . '/js/theme-customizer.js', array( 'customize-preview' ), '20120827', true );
}
add_action( 'customize_preview_init', 'twentytwelve_customize_preview_js' );

function pagePermalink() {  
    the_permalink();  
}
add_shortcode('permalink', 'pagePermalink');

// FUNCTIONS FOR BUSINESS INFORMATION TAGS
function companyname() {
	{
		$companyname = ot_get_option( 'companyname', 'Silicon Solar Inc' );
		return $companyname;
	}
}
function companyurl() {
	{
		$companyurl = ot_get_option( 'companyurl', 'www.SiliconSolar.com' );
		return $companyurl;
	}
}
function companylogo() {
	{
		$companylogo = ot_get_option( 'companylogo' );
		return $companylogo;
	}
}
function companyaddress() {
	{
		$companyaddress = ot_get_option( 'companyaddress', '56 Broome Corporate Pkwy' );
		return $companyaddress;
	}
}
function companycity() {
	{
		$companycity = ot_get_option( 'companycity', 'Conklin' );
		return $companycity;
	}
}
function companystate() {
	{
		$companystate = ot_get_option( 'companystate', 'NY' );
		return $companystate;
	}
}
function companyzipcode() {
	{
		$companyzipcode = ot_get_option( 'companyzipcode', '13748' );
		return $companyzipcode;
	}
}
function companyphone() {
	{
		$companyphone = ot_get_option( 'companyphone', '1.800.786.0329' );
		return $companyphone;
	}
}
function companyfax() {
	{
		$companyfax = ot_get_option( 'companyax', '1.800.653.8540' );
		return $companyfax;
	}
}
function companyhours() {
	{
		$companyhours = ot_get_option( 'companyhours', 'M-F 9am to 530pm EST' );
		return $companyhours;
	}
}
function companyfacebook() {
	{
		$companyfacebook = ot_get_option( 'companyfacebook' );
		return $companyfacebook;
	}
}
function companytwitter() {
	{
		$companytwitter = ot_get_option( 'companytwitter' );
		return $companytwitter;
	}
}
function companylinkedin() {
	{
		$companylinkedin = ot_get_option( 'companylinkedin' );
		return $companylinkedin;
	}
}
function companygoogle() {
	{
		$companygoogle = ot_get_option( 'companygoogle' );
		return $companygoogle;
	}
}
function companyyoutube() {
	{
		$companyyoutube = ot_get_option( 'companyyoutube' );
		return $companyyoutube;
	}
}

class woocom_subcats extends WP_Widget {
    
    function __construct()
    {
	$params = array(
		'name' => 'WooCommerce Subcategories widget',
	    'description' => 'Shows subcategories from chosen category' // plugin description that is showed in Widget section of admin panel
	);

	parent::__construct('woocom_subcats', '', $params);
    }
    
    function form($instance)
    {
	extract($instance);

	$taxlist = get_terms('product_cat', 'hide_empty=0');
	?>
		<p>
		    <label for="<?php echo $this->get_field_id('title'); ?>">Title: </label>
		    <input
			type="text"
			class="widefat"
			id="<?php echo $this->get_field_id('title'); ?>"
			name="<?php echo $this->get_field_name('title'); ?>"
			value="<?php if(isset($title)) echo esc_attr($title) ?>"
		    />
		</p>
		<p>
			<select
				id="<?php echo $this->get_field_id('catslist'); ?>"
				name="<?php echo $this->get_field_name('catslist'); ?>"
			>
				<?php
				foreach ($taxlist as $tax) 
				{
					if(get_term_children( $tax->term_id, 'product_cat' )) 
					{
						if(isset($catslist) && $catslist == $tax->term_id) $selected = ' selected="selected"';
						else $selected = '';
						echo '<option value="'.$tax->term_id.'"'.$selected.'>'.$tax->name.'</option>';						
					}
				}
				?>
			</select>
		</p>
	    <!--some html with input fields-->
	<?php
    }
    
    function widget($args, $instance)
    {
	extract($args);
	extract($instance);

	echo $before_widget;
	    echo $before_title . $title . $after_title;
	    echo '<ul>';
	    if(isset($catslist))
		{
			$args = array(
				'title_li'           => '',
				'show_option_none'   => '',
				'hide_empty'         => 0,
				'child_of'           => $post->ID,
				'taxonomy'           => 'product_cat'
			);
			wp_list_categories( $args );
		}
		echo '</ul>';

	echo $after_widget;
    }
}

add_action('widgets_init', 'woocom_subcats_register_function');

function woocom_subcats_register_function()
{
    register_widget('woocom_subcats');
}

function searchbar( $atts ) {
    ob_start();
    dynamic_sidebar('pagesearch');
    $html = ob_get_contents();
    ob_end_clean();
    return $html;
}

function FourCategories() {
    return 'Thank you so much for reading! And remember to subscribe to our RSS feed. ';
}
add_shortcode('fourcategories', 'FourCategories');

// Create A Featured Product For Each Category Using Shortcode : Usage : [featuredproduct num="1" category="flexible-solar-panels"]

class WC_Shortcodes {

	public function __construct() {

		add_shortcode( 'featured_cat_product', array( $this, 'featured_cat_product' ) );

	}

/**
	 * List products in a category shortcode
	 *
	 * @access public
	 * @param array $atts
	 * @return string
	 */
	function featured_cat_product( $atts ){
		global $woocommerce, $woocommerce_loop;

	  	if ( empty( $atts ) ) return;

		extract( shortcode_atts( array(
			'columns' 		=> '4',
		  	'orderby'   	=> 'title',
		  	'order'     	=> 'desc',
		  	'category'		=> ''
			), $atts ) );

		if ( ! $category ) return;

		// Default ordering args
		$ordering_args = $woocommerce->query->get_catalog_ordering_args( $orderby, $order );

	  	$args = array(
			'post_type'				=> 'product',
			'post_status' 			=> 'publish',
			'ignore_sticky_posts'	=> 1,
			'orderby' 				=> $ordering_args['orderby'],
			'order' 				=> $ordering_args['order'],
			'posts_per_page' 		=> 1,
			'meta_query' 			=> array(
				array(
					'key' 			=> '_visibility',
					'value' 		=> array('catalog', 'visible'),
					'compare' 		=> 'IN'
				)
			),
			'tax_query' 			=> array(
		    	array(
			    	'taxonomy' 		=> 'product_cat',
					'terms' 		=> array( esc_attr($category) ),
					'field' 		=> 'slug',
					'operator' 		=> 'IN'
				)
		    )
		);

		if ( isset( $ordering_args['meta_key'] ) ) {
	 		$args['meta_key'] = $ordering_args['meta_key'];
	 	}

	  	ob_start();

		$products = new WP_Query( $args );

		$woocommerce_loop['columns'] = $columns;

		if ( $products->have_posts() ) : ?>

			<?php woocommerce_product_loop_start(); ?>

				<?php while ( $products->have_posts() ) : $products->the_post(); ?>

					<?php woocommerce_get_template_part( 'content', 'product' ); ?>

				<?php endwhile; // end of the loop. ?>

			<?php woocommerce_product_loop_end(); ?>

		<?php endif;

		wp_reset_postdata();

		return '<div class="woocommerce">' . ob_get_clean() . '</div>';
	}
}

// Load The Help Guide Menu Tab  
require_once (TEMPLATEPATH . '/customfunctions/help-tabs.php'); 


function get_category_id($cat_name){
	$term = get_term_by('name', $cat_name, 'product_cat');
	return $term->term_id;
}

// Custom Featured Products ShortCode - Matt B - 2/2013
function featuredProducts() {
	$featuredproducts = new wp_Query('post_type=product&meta_key=featuredproduct&meta_value=highlight&posts_per_page=3');
		while ($featuredproducts->have_posts()) : $featuredproducts->the_post(); 
		$image  = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'single-post-thumbnail');
		$list .= '<li class="product">';
		$list .= '<a href="' . get_permalink() . '">';
		$list .= '<img src="' . $image[0] . '" alt="' . get_the_title() . '" />';
		$list .= '<h3>' . get_the_title() . '</h3>';
		$list .= '</a>';
		$list .= '<a href="' . get_permalink() . '" class="button">View Details</a>';
		$list .= '</li>';
	endwhile;
	$featuredproductstwo = new wp_Query('post_type=product&meta_key=featuredproduct&meta_value=highlight&posts_per_page=1&offset=3');
		while ($featuredproductstwo->have_posts()) : $featuredproductstwo->the_post(); 
		$imagetwo  = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'single-post-thumbnail');
		$listtwo .= '<li class="product last">';
		$listtwo .= '<a href="' . get_permalink() . '">';
		$listtwo .= '<img src="' . $imagetwo[0] . '" alt="' . get_the_title() . '" />';
		$listtwo .= '<h3>' . get_the_title() . '</h3>';
		$listtwo .= '</a>';
		$listtwo .= '<a href="' . get_permalink() . '" class="button">View Details</a>';
		$listtwo .= '</li>';
	endwhile;
    
    wp_reset_query();
    
    return '<h2 class="pagesubsectionheader" style="margin-top:20px;">Other Customers Have Loved...</h2><ul class="products">' . $list . '' . $listtwo . '</ul>';
	
}
add_shortcode('featuredproducts', 'featuredProducts');

// Add A "Recent Help-Guides & How-To's For The Dashboard
add_action('wp_dashboard_setup', 'my_custom_dashboard_widgets');
 
function my_custom_dashboard_widgets() {
global $wp_meta_boxes;

wp_add_dashboard_widget('custom_help_widget', 'Recent Help &amp; How-To Guides', 'custom_dashboard_help');
}

function custom_dashboard_help() {
$args = array('number_posts' => 5);
$rplist .= include ('/home/silicons/public_html/wp-content/themes/siliconsolar/admin-product-help-tab.php');
$rplist .= include ('/home/silicons/public_html/wp-content/themes/siliconsolar/admin-category-help-tab.php');
$rplist .= include ('/home/silicons/public_html/wp-content/themes/siliconsolar/admin-orders-help-tab.php');
$rplist .= include ('/home/silicons/public_html/wp-content/themes/siliconsolar/admin-docimages-help-tab.php');
$rplist .= include ('/home/silicons/public_html/wp-content/themes/siliconsolar/admin-customtype-help-tab.php');
$rplist .= include ('/home/silicons/public_html/wp-content/themes/siliconsolar/admin-other-help-tab.php');

echo $rplist;
}

//Function To Check If A Page Has Child Pages
function post_have_children($id){
	$children = get_pages('child_of='.$id);
	if(count($children) == 0){
		return false;
	}
	else{
		return true;
	}
}

// Function To Create A Tag Cloud For Tags On Posts, Products, Documents, Etc
function my_tag_cloud_filter($args = array()) {
   $args['smallest'] = 10;
   $args['largest'] = 15;
   $args['unit'] = 'px';
   $args['separator'] = ' &amp;nbsp; ';
   $args['orderby'] = 'name';
   $args['taxonomy'] = array('product_tag');
   return $args;
}
add_filter('widget_tag_cloud_args', 'my_tag_cloud_filter', 100);

/**
function customFShare() {
    $like_results = file_get_contents('http://graph.facebook.com/'. get_permalink());
    $like_array = json_decode($like_results, true);
    $like_count =  $like_array['shares'];
    return ($like_count ) ? $like_count : "0";
}
function customFShareShortcode( $atts, $content = null ) {
    extract(shortcode_atts(array(
       'type' => ''
    ), $atts));
    return "<a href='http://www.facebook.com/sharer/sharer.php?u=". get_permalink() ."' rel='nofollow' class='shareCircle'><strong>Share</strong> <span>". customFShare() ."</span></a>";
}
add_shortcode('customshare', 'customFShareShortcode');
 * 
 */

defined('ABSPATH') or die('cannot load directly');
 
/**
 * Function prepares the current theme for watermarking
 * 
 * @return string
 */
add_action('init', 'theme_supports_watermarks', 100);
function theme_supports_watermarks()
{
	if (!current_theme_supports('watermarks')) return false;
	add_filter('update_attached_file', 'watermark_image', 1, 1);
	add_filter('image_make_intermediate_size', 'redrokk_watermarked_thumbs', 1, 1);
	add_filter('wp_generate_attachment_metadata', 'redrokk_watermarked_original', 20, 2);
}
 
/**
 * 
 * 
 * @param integer $size
 */
function add_watermark_on_size( $size, $args = array() )
{
	global $watermark;
	
	if ($watermark === null) {
		$watermark = array();
	}
	if (!isset($watermark[$size])) {
		$watermark[$size] = array();
	}
	
	$watermark[$size][] = $args;
	return;
}
 
/**
 * Function will overlay the watermark onto the original image 
 * 
 * @param int $attachment_id Attachment Id to process.
 * @param string $file Filepath of the Attached image.
 * @return mixed Metadata for attachment.
 */
function redrokk_watermarked_original( $metadata, $attachment_id )
{
	global $watermark;
	
	if (isset($watermark['original']))
	{
		foreach ((array)$watermark['original'] as $args)
		{
			$water = redrokk_watermark_class::getInstance(
				ABSPATH.'wp-content'.DIRECTORY_SEPARATOR.'uploads'.DIRECTORY_SEPARATOR.$metadata['file'], 
				$args
			);
			$paths = $water->save();
		}
	}
	
	return $metadata;
}
 
/**
 * Function will overlay the watermark onto the specific image size 
 * 
 * @param $resized_file
 */
function redrokk_watermarked_thumbs( $resized_file )
{
	global $watermark;
	
	if ($watermark !== null)
	{
		list($width, $height, $type, $attr) = getimagesize($resized_file);
		
		// if the size matches then watermark this image 
		$w = in_array($width, array_keys($watermark));
		if ($w || in_array('all', array_keys($watermark))) 
		{
			foreach ((array)$watermark[ $w ?$width :'all'] as $args)
			{
				$water = redrokk_watermark_class::getInstance($resized_file, $args);
				$paths = $water->save();
			}
		}
	}
	
	return $resized_file;
}
 
/**
 * Function will overlay the given watermark on the image and
 * then save the new file, overwriting the given image
 * 
 * @param string $image
 * @param string $watermark
 * @param string $orientation
 * @param int $padding
 * @param int $opacity
 */
function watermark_image( $image, $watermark = NULL, $orientation = NULL, $padding = NULL, $opacity = NULL )
{
	global $watermark;
	
	// close if theres a specific size
	if ($watermark !== null) return $image;
	
	//get the real path
	$image = str_replace(site_url(), ABSPATH, $image);
	$path = pathinfo( $image );
	
	$backup = $path['dirname'].DIRECTORY_SEPARATOR
			. $path['filename']
			. '-original' . '.' . $path['extension'];
	
	// making sure that we don't mess up any important images
	if (!file_exists( $backup ))
	{
		if (!copy( $image, $backup ))
		{
			// define('WATERMARK_BACKUP', false);
			if (!defined('WATERMARK_BACKUP'))
			{
				trigger_error(__FUNCTION__.': Could not create a backup of the original,'
					. " to override define('WATERMARK_BACKUP', false);");
				return $image;
			}
			elseif (WATERMARK_BACKUP) 
			{
				trigger_error(__FUNCTION__.': Could not create a backup of the original.');
				return $image;
			}
		}
		
	} // just making sure that we dont add the watermark more then once
	else 
	{
		@copy( $backup, $image );
	}
	
	// setting the stage 
	$args = array();
	if ($watermark !== NULL) {
		$args['watermark'] = $watermark;
	}
	if ($orientation !== NULL) {
		$args['orientation'] = $orientation;
	}
	if ($padding !== NULL) {
		$args['padding'] = $padding;
	}
	if ($opacity !== NULL) {
		$args['opacity'] = $opacity;
	}
	$water = redrokk_watermark_class::getInstance($image, $args);
	$path = $water->save();
	
	return $path['file'];
}
 
/**
 * @author Anonymous
 * @tutorial https://gist.github.com/2045951
 *  
 */
class redrokk_watermark_class
{
	/**
	 * Contains the original watermark image
	 * 
	 * The file should be a PNG-8 format file, not PNG-24. 
	 * There’s a bug in the current version of GD, which doesn’t support 
	 * PNG-24 correctly.
	 * 
	 * @var string
	 */
	var $watermark;
	
	/**
	 * Contains a block of information about the image
	 * 
	 * @var string
	 */
	var $_wData = array();
	
	/**
	 * Contains the original image to watermark
	 * 
	 * @var string
	 */
	var $primary;
	
	/**
	 * Contains a block of information about the image
	 * 
	 * @var string
	 */
	var $_pData = array();
	
	/**
	 * Contains the orientation for the watermark. System defaults to the bottom
	 * right.
	 * 
	 * @example
	 * 	bottom
	 * 	top
	 * 	left
	 * 	right
	 * 
	 * @var string
	 */
	var $orientation = 'bottom right';
	
	/**
	 * How much padding between the watermark and the edges
	 * 
	 * @var string|array
	 */
	var $padding = 5;
	
	/**
	 * The opacity strength to apply when merging. 0 is hidden and 100 is full opacity.
	 * 
	 * @var int
	 */
	var $opacity = 90;
	
	/**
	 * We only need to run the merge once.
	 * 
	 * @var boolean
	 */
	var $_merged = false;
	
	/**
	 * The relation from the top
	 * 
	 * @var string
	 */
	var $top = 'bottom';
	
	/**
	 * The relation from the left
	 * 
	 * @var string
	 */
	var $left = 'right';
	
	/**
	 * Parameters determines whether or not the system will use smart scaling
	 * and adjust the size of the watermark, according to the image size.
	 * 
	 * @var boolean
	 */
	var $scale = true;
	
	/**
	 * Extends the canvas beyond the image for the watermark
	 * 
	 * @var boolean
	 */
	var $extendcanvas = false;
	
	/**
	 * Adds a background line behind the watermark
	 * 
	 * @var boolean
	 */
	var $horizontalline = false;
	
	/**
	 * Shall we save an original?
	 * 
	 * @var boolean
	 */
	var $backup = false;
	
	/**
	 * Constructor.
	 * 
	 */
	function __construct( $options = array() )
	{
		// define('WATERMARK_SOURCE', '/path/to/file.png');
		if (defined('WATERMARK_SOURCE')) {
			$this->set('watermark', WATERMARK_SOURCE);
		}
		
		//define('WATERMARK_ORIENTATION', 'bottom right');
		if (defined('WATERMARK_ORIENTATION')) {
			$this->set('orientation', WATERMARK_ORIENTATION);
		}
		
		//define('WATERMARK_PADDING', 5);
		if (defined('WATERMARK_PADDING')) {
			$this->set('padding', WATERMARK_PADDING);
		}
		
		//define('WATERMARK_OPACITY', 90);
		if (defined('WATERMARK_OPACITY')) {
			$this->set('opacity', WATERMARK_OPACITY);
		}
		
		// initializing
		$this->setProperties($options);
	}
	
	/**
	 * Function saves the newly created image into the uploads folder and returns 
	 * an array which includes the file path.
	 * 
	 * @see wp_upload_bits(); http://codex.wordpress.org/Function_Reference/wp_upload_bits
	 * 
	 * @param string $path
	 * 
	 * @return array
	 */
	function save( $path = NULL )
	{
		do_action(get_class().'::save', $this);
		
		//merging if we have not yet merged
		$bits = $this->getWatermarkedImageResource();
		
		if ($path === NULL) {
			$path = $this->primary;
		}
		
		if ($this->backup)
		{
			rename( $path, 
				$this->_pData['path'].'/'.$this->_pData['name'].".original.".$this->_pData['ext'] );
		}
		
		$parts = pathinfo( $path );
		$name = $this->_pData['name'].'.'.$parts['extension'];
		
		$wp_filetype = wp_check_filetype( $name );
		if (!$wp_filetype['ext']) {
			return array( 'error' => __( 'Invalid file type' ) );
		}
		
		if (!wp_mkdir_p( dirname( $path ) )) {
			$message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), dirname( $new_file ) );
			return array( 'error' => $message );
		}
		
		$ifp = @ fopen( $path, 'wb' );
		if (!$ifp) {
			return array( 'error' => sprintf( __( 'Could not write file %s' ), $path ) );
		}
		
		@fwrite( $ifp, $bits );
		fclose( $ifp );
		clearstatcache();
 
		// Set correct file permissions
		$stat = @ stat( dirname( $path ) );
		$perms = $stat['mode'] & 0007777;
		$perms = $perms & 0000666;
		@ chmod( $path, $perms );
		clearstatcache();
 
		// Compute the URL
		$url = str_replace(ABSPATH, site_url().'/', $path);
		$options = array( 'file' => $path, 'url' => $url, 'error' => false );
		
		if (0) { 
			echo '<pre> $options : ';
			var_export($options);
			echo "\r".'$this : ';
			print_r(get_object_vars($this));
			echo '</pre>';
			die();
		}
 
		return $options;
	}
	
	/**
	 * Method merges the watermark image with the primary image to be watermarked,
	 * saves the final image and returns the path
	 * 
	 * @notice use of the PNG format; GD 2.0+ has removed compatibility with GIF images
	 * 
	 * @see imagecopymerge
	 * int imagecopymerge ( 
	 * 		resource dst_im, 
	 * 		resource src_im, 
	 * 		int dst_x, 
	 * 		int dst_y, 
	 * 		int src_x, 
	 * 		int src_y, 
	 * 		int src_w, 
	 * 		int src_h, 
	 * 		int pct )  
	 * 
	 * @tutorial
	 * Copy a part of src_im onto dst_im starting at the x,y coordinates src_x, 
	 * src_y with a width of src_w and a height of src_h. The portion defined will 
	 * be copied onto the x,y coordinates, dst_x and dst_y. The two images will be 
	 * merged according to pct which can range from 0 to 100.
	 * 
	 */
	function merge()
	{
		// merge the image if it has not yet been merged
		if (!$this->_merged) 
		{
			// additional adjustments
			$this->canvassize();
			$this->imageline();
			
			// offering others an opportunity
			$args = apply_filters('redrokk_watermark_args', array(
				'primary' => $this->_pData['img'],
				'watermark' => $this->_wData['img'],
				'dst_x' => $this->getDestinationX(),
				'dst_y' => $this->getDestinationY(),
				'src_x' => 0,
				'src_y' => 0,
				'src_w' => $this->_wData['x'],
				'src_h' => $this->_wData['y'],
				'opacity' => $this->opacity
			), $this);
			
			$this->_merged = call_user_func_array('imagecopymerge', $args);
		}
		
		return $this->_merged;
	}
	
	/**
	 * Returns the image as a string
	 * 
	 */
	function getWatermarkedImageResource()
	{
		$this->merge();
		
		ob_start();
		imagejpeg( $this->_pData['img'] );
		return ob_get_clean();
	}
	
	/**
	 * Creates an image from a given file
	 * 
	 * @param string $file 
	 * @param string $type 
	 */
	function getImageResource( $file, $type = 3 )
	{
		//initializing
		$img = false;
		
		if ($type === NULL) {
			$size = getimagesize( $file );
			$type = $size['mime'];
		}
		
		switch ($type) {
			default:
			case 3:
			case '3':
			case 'image/png':
				$img = imagecreatefrompng($file);
				break;
			case 2:
			case '2':
			case 'image/jpeg':
				$img = imagecreatefromjpeg($file);
				break;
			case 'image/gif':
				$img = imagecreatefromgif($file);
				break;
		}
		
		return $img;
	}
	
	/**
	 * Determines information about the given image and returns it as an array
	 * 
	 * @param $file
	 */
	function getImageData( $file )
	{
		//initializing
		if (!$size = getimagesize( $file )) return false;
		
		$data = array();
		
		list($width, $height, $type, $attr) = $size;
		$data['x'] 		= $width;
		$data['y'] 		= $height;
		$data['mime'] 	= $type;
		
		$path_parts 	= pathinfo( $file );
		$data['path'] 	= $path_parts['dirname'];
		$data['name'] 	= $path_parts['filename'];
		$data['ext'] 	= $path_parts['extension'];
		
		$data['img'] 	= $this->getImageResource( $file, $type );
		
		return $data;
	}
	
	/**
	 * Returns the proper y value for the given orientation
	 * 
	 */
	function getDestinationY()
	{
		// if top
		if ($this->isTop())
		{ 
			return $this->getPaddingY();
		}
		// if center
		elseif ($this->isYCenter())
		{
			return @ceil( ($this->_pData['y'] - $this->_wData['y']) / 2 );
		}
		
		// bottom is default
		return $this->_pData['y'] - $this->_wData['y'] - $this->getPaddingY();
	}
	
	/**
	 * Returns the proper x value for the given orientation
	 * 
	 */
	function getDestinationX()
	{
		// if left
		if ($this->isLeft())
		{ 
			return $this->getPaddingX();
		}
		// if center
		elseif ($this->isXCenter())
		{
			return @ceil( ($this->_pData['x'] - $this->_wData['x']) / 2 );
		}
		
		// right is default
		return $this->_pData['x'] - $this->_wData['x'] - $this->getPaddingX();
	}
	
	/**
	 * Returns boolean value determining if the orientation asked for is
	 * an accurate orientation.
	 * 
	 * @return boolean
	 */
	function isTop() {
		return strpos(strtolower($this->top),'top') !== false;
	}
	function isYCenter() {
		return strpos(strtolower($this->top),'center') !== false;
	}
	function isBottom() {
		return strpos(strtolower($this->top),'bottom') !== false;
	}
	function isLeft() {
		return strpos(strtolower($this->left),'left') !== false;
	}
	function isXCenter() {
		return strpos(strtolower($this->left),'center') !== false;
	}
	function isRight() {
		return strpos(strtolower($this->left),'right') !== false;
	}
	
	/**
	 * Returns the y padding integer
	 * 
	 */
	function getPaddingY()
	{
		if (is_array($this->padding))
		{
			return $this->padding['y'];
		}
		return $this->padding;
	}
	
	/**
	 * Returns the x padding integer
	 * 
	 */
	function getPaddingX()
	{
		if (is_array($this->padding))
		{
			return $this->padding['x'];
		}
		return $this->padding;
	}
	
	/**
	 * Sets the padding
	 * 
	 */
	function setPadding( $value = NULL )
	{
		if ($value === NULL) return false;
		return $this->padding = $value;
	}
	
	/**
	 * Sets the top and left orientation
	 * 
	 */
	function setOrientation( $value = NULL )
	{
		if ($value === NULL) return false;
		
		// initializing
		$this->orientation = $value;
		$parts = explode(' ', $this->orientation);
		
		if (isset($parts[0])) {
			$this->setTop( $parts[0] );
		}
		if (isset($parts[1])) {
			$this->setLeft( $parts[1] );
		}
	}
	
	/**
	 * Sets the orientation from the top
	 * 
	 */
	function setTop( $value )
	{
		return $this->top = $value;
	}
	
	/**
	 * Sets the orientation from the left
	 * 
	 */
	function setLeft( $value )
	{
		return $this->left = $value;
	}
	
	/**
	 * Sets the primary image and processes it
	 * 
	 * @param string $value
	 */
	function setWatermark( $value = NULL )
	{
		if ($value === NULL) return false;
		
		//get the real path
		$value = str_replace(site_url(), ABSPATH, $value);
		
		//remember image
		$this->watermark = $value;
		
		//process this image
		if (!$this->_wData = $this->getImageData( $this->watermark )) {
			trigger_error(__CLASS__.": image is not a valid resource ($this->watermark)");
		}
	}
	
	/**
	 * Sets the primary image and processes it
	 * 
	 * @param string $value
	 */
	function setPrimary( $value = NULL )
	{
		if ($value === NULL) return false;
		
		//get the real path
		$value = str_replace(site_url(), ABSPATH, $value);
		
		//remember image
		$this->primary = $value;
		
		//process this image
		if (!$this->_pData = $this->getImageData( $this->primary )) {
			trigger_error(__CLASS__.": image is not a valid resource ($this->primary)");
		}
	}
	
	/**
	 * Extends the canvas size of the image
	 * 
	 */
	function canvassize()
	{
		if (!$this->extendcanvas) return false;
		
		$extend = $this->_wData['y'] + $this->padding + 2;
		
		// resizing the canvas
		$blackcanvas = imagecreatetruecolor($this->_pData['x'], $this->_pData['y'] + $extend );
		imagecopyresampled(
			$blackcanvas, // Destination image link resource.
			$this->_pData['img'], // Source image link resource.
			0, // x-coordinate of destination point.
			0, // y-coordinate of destination point.
			0, // x-coordinate of source point.
			0, // y-coordinate of source point.
			$this->_pData['x'], // Destination width.
			$this->_pData['y'], // Destination height.
			$this->_pData['x'], // Source width.
			$this->_pData['y'] // Source height.
		);
		
		$this->_pData['y'] = $this->_pData['y'] + $extend;
		$this->_pData['img'] = $blackcanvas;
	}
	
	/**
	 * Creates the horizontal background line
	 * 
	 */
	function imageline()
	{
		if (!$this->horizontalline) return false;
		
		//initializing
		$y = ceil($this->getDestinationY() + ($this->_wData['y'] /2));
		$im = imagecreatetruecolor ( 140, 140 );
		
		// creating the color
		$color = imagecolorallocate($im, 255, 255, 255);
		
		// merging the line with the primary image
		$this->imagelinethick(
			$this->_pData['img']
			,0
			,$y
			,$this->_pData['x']
			,$y
			,$color
			,$this->_wData['y'] + $this->padding + 2
		);
		
		return true;
	}
	
	/**
	 * This way it works well only for orthogonal lines imagesetthickness($image, $thick);
	 * return imageline($image, $x1, $y1, $x2, $y2, $color);
	 * 
	 * @param $image
	 * @param $x1
	 * @param $y1
	 * @param $x2
	 * @param $y2
	 * @param $color
	 * @param $thick
	 */
	function imagelinethick($image, $x1, $y1, $x2, $y2, $color, $thick = 1)
	{
		if ($thick == 1)
			return imageline($image, $x1, $y1, $x2, $y2, $color);
	    
	    $t = $thick / 2 - 0.5;
	    
	    if ($x1 == $x2 || $y1 == $y2)
			return imagefilledrectangle($image, round(min($x1, $x2) - $t), round(min($y1, $y2) - $t), round(max($x1, $x2) + $t), round(max($y1, $y2) + $t), $color);
	    
	    $k = ($y2 - $y1) / ($x2 - $x1); //y = kx + q
	    $a = $t / sqrt(1 + pow($k, 2));
	    
	    $points = array(
			round($x1 - (1+$k)*$a), round($y1 + (1-$k)*$a),
			round($x1 - (1-$k)*$a), round($y1 - (1+$k)*$a),
			round($x2 + (1+$k)*$a), round($y2 - (1-$k)*$a),
			round($x2 + (1-$k)*$a), round($y2 + (1+$k)*$a),
	    );
	    
	    imagefilledpolygon($image, $points, 4, $color);
	    return imagepolygon($image, $points, 4, $color);
	}
 
	/**
	 * Method to bind an associative array or object to the JTable instance.This
	 * method only binds properties that are publicly accessible and optionally
	 * takes an array of properties to ignore when binding.
	 *
	 * @param   mixed  $src	 An associative array or object to bind to the JTable instance.
	 * @param   mixed  $ignore  An optional array or space separated list of properties to ignore while binding.
	 *
	 * @return  boolean  True on success.
	 *
	 * @link	http://docs.joomla.org/JTable/bind
	 * @since   11.1
	 */
	public function bind($src, $ignore = array())
	{
		// If the source value is not an array or object return false.
		if (!is_object($src) && !is_array($src))
		{
			trigger_error('Bind failed as the provided source is not an array.');
			return false;
		}
 
		// If the source value is an object, get its accessible properties.
		if (is_object($src))
		{
			$src = get_object_vars($src);
		}
 
		// If the ignore value is a string, explode it over spaces.
		if (!is_array($ignore))
		{
			$ignore = explode(' ', $ignore);
		}
 
		// Bind the source value, excluding the ignored fields.
		foreach ($this->getProperties() as $k => $v)
		{
			// Only process fields not in the ignore array.
			if (!in_array($k, $ignore))
			{
				if (isset($src[$k]))
				{
					$this->$k = $src[$k];
				}
			}
		}
 
		return true;
	}
	
	/**
	 * Set the object properties based on a named array/hash.
	 *
	 * @param   mixed  $properties  Either an associative array or another object.
	 *
	 * @return  boolean
	 *
	 * @since   11.1
	 *
	 * @see	 set() 
	 */
	public function setProperties($properties)
	{
		if (is_array($properties) || is_object($properties))
		{
			foreach ((array) $properties as $k => $v)
			{
				// Use the set function which might be overridden.
				$this->set($k, $v);
			}
			return true;
		}
 
		return false;
	}
	
	/**
	 * Modifies a property of the object, creating it if it does not already exist.
	 *
	 * @param   string  $property  The name of the property.
	 * @param   mixed   $value	 The value of the property to set.
	 *
	 * @return  mixed  Previous value of the property.
	 *
	 * @since   11.1
	 */
	public function set($property, $value = null)
	{
		$_property = 'set'.str_replace(' ', '', ucwords(str_replace('_', ' ', $property)));
		if (method_exists($this, $_property)) {
			return $this->$_property($value);
		}
		
		$previous = isset($this->$property) ? $this->$property : null;
		$this->$property = $value;
		return $previous;
	}
	
	/**
	 * Returns an associative array of object properties.
	 *
	 * @param   boolean  $public  If true, returns only the public properties.
	 *
	 * @return  array 
	 *
	 * @see	 get()
	 */
	public function getProperties($public = true)
	{
		$vars = get_object_vars($this);
		if ($public)
		{
			foreach ($vars as $key => $value)
			{
				if ('_' == substr($key, 0, 1))
				{
					unset($vars[$key]);
				}
			}
		}
 
		return $vars;
	}
	
	/**
	 * contains the current instance of this class
	 * 
	 * @var object
	 */
	static $_instances = null;
	
	/**
	 * Method is called when we need to instantiate this class
	 * 
	 * @param array $options
	 */
	public static function getInstance( $primary, $options = array() )
	{
		if (!isset(self::$_instances[$primary]))
		{
			$options['primary'] = $primary;
			$class = get_class();
			self::$_instances[$primary] =& new $class($options);
		}
		return self::$_instances[$primary];
	}
}